package com.tonyodev.fetch2core;

import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

import org.jetbrains.annotations.NotNull;

/**
 * 通信工具类
 *
 * @since 2021-05-20
 */
public class HandlerWrapper {
    private final Object lock = new Object();
    private boolean closed = false;
    private int usageCounter = 0;
    private EventHandler workerTaskHandler;
    private EventHandler handler;
    @NotNull
    private String namespace;

    /**
     * 初始化
     *
     * @param namespace 名称
     * @param backgroundHandler 后台handler
     */
    public HandlerWrapper(@NotNull String namespace, EventHandler backgroundHandler) {
        this.namespace = namespace;
        this.handler = backgroundHandler;
        if (backgroundHandler == null) {
            EventRunner eventRunner = EventRunner.create(namespace);
            this.handler = new EventHandler(eventRunner);
        }
    }

    /**
     * 初始化
     *
     * @param namespace 名称
     */
    public HandlerWrapper(@NotNull String namespace) {
        this(namespace, null);
    }

    public String getNamespace() {
        return namespace;
    }

    public boolean isClosed() {
        return closed;
    }

    public void setClosed(boolean closed) {
        this.closed = closed;
    }

    public int getUsageCounter() {
        return usageCounter;
    }

    public void setUsageCounter(int usageCounter) {
        this.usageCounter = usageCounter;
    }

    public EventHandler getWorkerTaskHandler() {
        return workerTaskHandler;
    }

    public void setWorkerTaskHandler(EventHandler workerTaskHandler) {
        this.workerTaskHandler = workerTaskHandler;
    }

    /**
     * 发送一个Runnable任务到事件队列
     *
     * @param runnable 任务
     */
    public void post(Runnable runnable) {
        synchronized (lock) {
            if (!closed) {
                handler.postTask(runnable);
            }
        }
    }

    /**
     * 发送一个延时Runnable任务到事件队列
     *
     * @param runnable 任务
     * @param delayMillis 时间
     */
    public void postDelayed(Runnable runnable, long delayMillis) {
        synchronized (lock) {
            if (!closed) {
                handler.postTask(runnable, delayMillis);
            }
        }
    }

    /**
     * 删除任务
     *
     * @param runnable 任务
     */
    public void removeCallbacks(Runnable runnable) {
        synchronized (lock) {
            if (!closed) {
                handler.removeTask(runnable);
            }
        }
    }

    /**
     * 次数加1
     */
    public void incrementUsageCounter() {
        synchronized (lock) {
            if (!closed) {
                usageCounter += 1;
            }
        }
    }

    /**
     * 次数减1
     */
    public void decrementUsageCounter() {
        synchronized (lock) {
            if (!closed) {
                if (usageCounter == 0) {
                    return;
                }
                usageCounter -= 1;
            }
        }
    }

    /**
     * 获取次数
     *
     * @return 次数
     */
    public int usageCount() {
        synchronized (lock) {
            if (!closed) {
                return usageCounter;
            } else {
                return 0;
            }
        }
    }

    /**
     * 获取EventRunner
     *
     * @return EventRunner
     */
    public EventRunner getEventRunner() {
        synchronized (lock) {
            return handler.getEventRunner();
        }
    }

    /**
     * 执行工作任务
     *
     * @param runnable 任务
     */
    public void executeWorkerTask(Runnable runnable) {
        synchronized (lock) {
            if (!closed) {
                if (workerTaskHandler == null) {
                    workerTaskHandler = getNewWorkerTaskHandler();
                }
                workerTaskHandler.postTask(runnable);
            }
        }
    }

    /**
     * 获取工作中EventRunner
     *
     * @return EventRunner
     */
    public EventRunner getWorkTaskLooper() {
        synchronized (lock) {
            EventHandler workerHandler = workerTaskHandler;
            if (workerHandler == null) {
                EventHandler newHandler = getNewWorkerTaskHandler();
                workerTaskHandler = newHandler;
                return newHandler.getEventRunner();
            } else {
                return workerHandler.getEventRunner();
            }
        }
    }

    private EventHandler getNewWorkerTaskHandler() {
        EventRunner handlerThread = EventRunner.create(namespace + " worker task");
        return new EventHandler(handlerThread);
    }

    /**
     * 关闭任务
     */
    public void close() {
        synchronized (lock) {
            if (!closed) {
                closed = true;
                try {
                    handler.removeAllEvent();
                    handler.getEventRunner().stop();
                } catch (Exception e) {
                }
                try {
                    EventHandler workerHandler = workerTaskHandler;
                    workerTaskHandler = null;
                    if (workerHandler != null) {
                        workerHandler.removeAllEvent();
                        if (workerHandler.getEventRunner() != null) {
                            workerHandler.getEventRunner().stop();
                        }
                    }
                } catch (Exception e) {
                }
            }
        }
    }
}
